package com.dht.xiao.jianye.dlclogfile;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Environment;

import com.lzy.okgo.OkGo;
import com.lzy.okgo.callback.StringCallback;
import com.lzy.okgo.model.HttpParams;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;

/**
 * Created by Administrator on 2018\9\23 0023.
 */

public class LogFileUtil {
    private static LogFileUtil instance;
    private Context context;
    private String SDPATH;
    private File fileDir;
    private String macno;
    private int trackLevel = 4;

    public static LogFileUtil getInstance() {
        if (instance == null) {
            instance = new LogFileUtil();
        }
        return instance;
    }

    /**
     * 初始化
     *
     * @param context
     * @param macno   设备编号
     */
    public void init(Context context, String macno) {
        this.context = context;
        this.macno = macno;
//        if (android.os.Environment.getExternalStorageState().equals(
//                android.os.Environment.MEDIA_MOUNTED)) {
//            spm("has");
//        } else {
//            spm("not");
//        }
        SDPATH = Environment.getExternalStorageDirectory().toString() + "/" + context.getPackageName() + "_logFiles";
        fileDir = new File(SDPATH);
        if (!fileDir.exists()) {
            fileDir.mkdirs();
        }

    }

    /**
     * 设置日志登记，通过showAllLevelMethod来判断应该使用第几级日志
     *
     * @param trackLevel
     */
    public void setTrackLevel(int trackLevel) {
        this.trackLevel = trackLevel;
    }

    /**
     * 展示所有登记下的日志
     *
     * @return
     */
    public String[] showAllLevelMethod() {
        StackTraceElement[] es = Thread.currentThread().getStackTrace();
        String[] methods = new String[es.length];
        int i = 0;
        for (StackTraceElement e : es) {
            methods[i] = e.getMethodName();
            i++;
        }
        return methods;
    }

    private List<String> list = new ArrayList<>();

    public void addLog(String log) {
        list.add(log);
        dealList();
    }

    private boolean isSaving;
    private void dealList() {
        if (!isSaving) {
            isSaving = true;
           // rxWriteData(list.get(0));
            saveLog(list.get(0));
        }
    }

    /**
     * 保存日志
     *
     * @param log
     */
    private void saveLog(String log) {
        File[] files = fileDir.listFiles();
        if (files != null && files.length > 90) {
            List<File> fileList = Arrays.asList(files);
            Collections.sort(fileList, new FileComparator(false));//根据字母排序
            fileList.get(0).delete();
        }
        StackTraceElement[] es = Thread.currentThread().getStackTrace();
        StackTraceElement e = null;
        if (es[trackLevel].getMethodName().contains("access")) {
            e = es[trackLevel + 1];
        } else {
            e = es[trackLevel];
        }
        String verCode = null;
        String verName = null;
        PackageManager manager = context.getPackageManager();
        try {
            PackageInfo info = manager.getPackageInfo(context.getPackageName(), 0);
            int versionCode = info.versionCode;
            verCode = versionCode + "";
            verName = info.versionName;
        } catch (PackageManager.NameNotFoundException e1) {
            e1.printStackTrace();
        }
        String model = Build.MODEL;
        String carrier = Build.MANUFACTURER;
        String androidVerCode = Build.VERSION.SDK_INT + "";
        String androidVerName = Build.VERSION.RELEASE + "";

        String fileName = e.getFileName();
        int lineNum = e.getLineNumber();
        String methodName = e.getMethodName();

        StringBuilder common = new StringBuilder();

        common.append("verCode:" + verCode + "\n").append("verName:" + verName + "\n")
                .append("model:" + model + "\n").append("brand:" + carrier + "\n")
                .append("androidVerCode:" + androidVerCode + "\n").append("androidVerName:" + androidVerName + "\n")
                .append("fileName:" + fileName + "\n").append("methodName:" + methodName + "\n")
                .append("lineNum:" + lineNum + "\n");

       // log = common.toString();

        StringBuilder sb = new StringBuilder();

        sb.append("time:" + timestampToDate(System.currentTimeMillis() + "", "yyyy-MM-dd HH:mm:ss") + "\n")
                .append("content:" + log);

        log = sb.toString();
        spm("log:" + log);

        sb.delete(0, sb.length());

        String today = timestampToDate(System.currentTimeMillis() + "", "yyyy-MM-dd");
        File file = new File(SDPATH + "/", macno + "_" + today + ".txt");
        if (!file.exists()) {
            log =  common.toString()+log;
        }
        String originContent = getLog(today);
        if (originContent != null) {
            log = originContent + "\n" + "- - - - - - - - - -" + "\n" + log;
        }
        FileOutputStream outputStream = null;
        BufferedOutputStream bufferedOutputStream = null;
        try {
            outputStream = new FileOutputStream(file);
            bufferedOutputStream = new BufferedOutputStream(outputStream);
            bufferedOutputStream.write(log.getBytes());
            bufferedOutputStream.flush();
        } catch (Exception e1) {
            e1.printStackTrace();
        } finally {
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
            if (bufferedOutputStream != null) {
                try {
                    bufferedOutputStream.close();
                } catch (Exception e2) {
                    e2.printStackTrace();
                }
            }
        }
        list.remove(0);
        isSaving = false;
        spm("save success");
        if (list.size() > 0) {
            dealList();
        }
    }
    /**
     * 保存日志
     *
     * @param log
     */
    private Observable<String> rxWriteData(final String log) {
        return Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String > emitter) throws Exception {
                File[] files = fileDir.listFiles();
                if (files != null && files.length > 90) {
                    List<File> fileList = Arrays.asList(files);
                    Collections.sort(fileList, new FileComparator(false));//根据字母排序
                    fileList.get(0).delete();
                }
                StackTraceElement[] es = Thread.currentThread().getStackTrace();
                StackTraceElement e = null;
                if (es[trackLevel].getMethodName().contains("access")) {
                    e = es[trackLevel + 1];
                } else {
                    e = es[trackLevel];
                }
                String verCode = null;
                String verName = null;
                PackageManager manager = context.getPackageManager();
                try {
                    PackageInfo info = manager.getPackageInfo(context.getPackageName(), 0);
                    int versionCode = info.versionCode;
                    verCode = versionCode + "";
                    verName = info.versionName;
                } catch (PackageManager.NameNotFoundException e1) {
                    e1.printStackTrace();
                }
                String model = Build.MODEL;
                String carrier = Build.MANUFACTURER;
                String androidVerCode = Build.VERSION.SDK_INT + "";
                String androidVerName = Build.VERSION.RELEASE + "";

                String fileName = e.getFileName();
                int lineNum = e.getLineNumber();
                String methodName = e.getMethodName();

                StringBuilder common = new StringBuilder();

                common.append("verCode:" + verCode + "\n").append("verName:" + verName + "\n")
                        .append("model:" + model + "\n").append("brand:" + carrier + "\n")
                        .append("androidVerCode:" + androidVerCode + "\n").append("androidVerName:" + androidVerName + "\n")
                        .append("fileName:" + fileName + "\n").append("methodName:" + methodName + "\n")
                        .append("lineNum:" + lineNum + "\n");

                // log = common.toString();

                String finalLog = log;

                StringBuilder sb = new StringBuilder();

                sb.append("time:" + timestampToDate(System.currentTimeMillis() + "", "yyyy-MM-dd HH:mm:ss") + "\n")
                        .append("content:" + finalLog);

                finalLog = sb.toString();
                spm("log:" + finalLog);

                sb.delete(0, sb.length());

                String today = timestampToDate(System.currentTimeMillis() + "", "yyyy-MM-dd");
                File file = new File(SDPATH + "/", macno + "_" + today + ".txt");
                if (!file.exists()) {
                    finalLog =  common.toString()+finalLog;
                }
                String originContent = getLog(today);
                if (originContent != null) {
                    finalLog = originContent + "\n" + "- - - - - - - - - -" + "\n" + finalLog;
                }
                FileOutputStream outputStream = null;
                BufferedOutputStream bufferedOutputStream = null;
                try {
                    outputStream = new FileOutputStream(file);
                    bufferedOutputStream = new BufferedOutputStream(outputStream);
                    bufferedOutputStream.write(finalLog.getBytes());
                    bufferedOutputStream.flush();
                } catch (Exception e1) {
                    e1.printStackTrace();
                } finally {
                    if (outputStream != null) {
                        try {
                            outputStream.close();
                        } catch (IOException e1) {
                            e1.printStackTrace();
                        }
                    }
                    if (bufferedOutputStream != null) {
                        try {
                            bufferedOutputStream.close();
                        } catch (Exception e2) {
                            e2.printStackTrace();
                        }
                    }
                }
                list.remove(0);
                isSaving = false;
                spm("save success");
                if (list.size() > 0) {
                    dealList();
                }
                emitter.onComplete();
            }
        });
    }

    /**
     * 获取当天日志
     *
     * @return
     */
    public String getLog() {
        String today = timestampToDate(System.currentTimeMillis() + "", "yyyy-MM-dd");
        return getLog(today);
    }

    /**
     * 根据日期获取日志
     *
     * @param date
     * @return
     */
    public String getLog(String date) {
        String content = null;
        File file = new File(SDPATH + "/", macno + "_" + date + ".txt");
        if (file.exists()) {
            try {
                FileInputStream inputStream = new FileInputStream(file);
                BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
                byte[] bys = new byte[1024];
                int len = 0;
                while ((len = bufferedInputStream.read(bys)) != -1) {
                    if (content == null) {
                        content = new String(bys, 0, len);
                    } else {
                        content = content + new String(bys, 0, len);
                    }
                }
            } catch (Exception e1) {
                e1.printStackTrace();
            }
        }
        return content;
    }

    /**
     * 获取当天日志文件
     *
     * @return
     */
    public File getFile() {
        String today = timestampToDate(System.currentTimeMillis() + "", "yyyy-MM-dd");
        return getFile(today);
    }

    /**
     * 根据日期获取日志文件
     *
     * @param date
     * @return
     */
    public File getFile(String date) {
        File file = new File(SDPATH + "/", macno + "_" + date + ".txt");
        if (file.exists()) {
            return file;
        } else {
            return null;
        }
    }

    /**
     * 时间戳转日期格式
     *
     * @param time
     * @param dateFormat "yyyy-MM-dd"
     * @return
     */
    public String timestampToDate(String time, String dateFormat) {
        int length = time.length();
        if (length == 13) {
            time = time.substring(0, 10);
        }

        long timeI = (long) Integer.parseInt(time);
        long temp = timeI * 1000L;
        Timestamp ts = new Timestamp(temp);
        Object date = new Date();

        try {
            date = ts;
        } catch (Exception var11) {
            var11.printStackTrace();
        }

        SimpleDateFormat formatter = new SimpleDateFormat(dateFormat);
        String dateString = formatter.format((Date) date);
        return dateString;
    }

    public boolean updateLogToServer(StringCallback callback) {
        String today = timestampToDate(System.currentTimeMillis() + "", "yyyy-MM-dd");
        return updateLogToServer(today, callback);
    }

    /**
     * 上传日志到服务器，通过http://anzhuologs.app.xiaozhuschool.com/App/Upload/logs访问
     *
     * @param date
     * @param callback
     * @return true文件存在，false文件不存在
     */
    public boolean updateLogToServer(String date, StringCallback callback) {
        File file = new File(SDPATH + "/", macno + "_" + date + ".txt");
        if (!file.exists()) {
            return false;
        }
        HttpParams params = new HttpParams();
        params.put("date", date);
        params.put("macNo", macno);
        params.put("packageName", context.getPackageName());
        params.put("file", file);
//        OkGoWrapper.instance().post("http://anzhuologs.app.xiaozhuschool.com/App/Upload/index", params, String.class, callback);
        OkGo.<String>post("http://anzhuologs.app.xiaozhuschool.com/App/Upload/index").params(params).execute(callback);
        return true;
    }

    private void spm(String msg) {
//        Log.d("spm", msg);
    }
}
